home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 42 / Amiga Format AFCD42 (Issue 126, Aug 1999).iso / -serious- / programming / basic / udpchat / udpfuncs.asc < prev    next >
Encoding:
Text File  |  1999-05-14  |  6.1 KB  |  182 lines

  1. ;-----------------------------------------------------------
  2. ;              UDP_Funcs  V1.4  23/04/99 based on
  3. ; Standard Blitz TCP Functions V1.5 by Paul Burkey (c)1997
  4. ; Compiled with help from Ercole Spiteri and Anton Reinauer
  5. ; You must have the bsdsocket.library setup in Blitz
  6. ;   by Anton Reinauer anton@ww.co.nz
  7. ;-----------------------------------------------------------
  8.  
  9. ;---------------------------------
  10. ; Standard UDP Blitz Functions
  11. ;---------------------------------
  12.  
  13. .Get_Host_By_Name        ; get a host structure by name (if exists), from a name server
  14. Function Get_Host_By_Name{host$,port.w,player}
  15.   SHARED host(),hostlen()
  16.  
  17.   *a.hostent=gethostbyname_(host$)     ; set up destination address to send packets to
  18.   If *a.hostent=0
  19.     Security_Warning{"Couldn't get Localhost name!",#HIGH}
  20.     Function Return False
  21.   EndIf
  22.  
  23.   ;Copy Details to our Sockaddrin structure
  24.  
  25.   bb=CopyMem_(*a.hostent\h_addr_list\ItemA,&host(player)\sin_addr,*a.hostent\h_length)
  26.  
  27.   host(player)\sin_port=port       ;Set port number
  28.   host(player)\sin_family=2        ;Set type to AT_INET
  29.   hostlen(player)=SizeOf.sockaddrin        ;Get length of structure sockaddrin
  30.  
  31.   Function Return True
  32. End Function
  33.  
  34. .Get_Host_By_Address      ; get a host structure by address (if exists), from a name server
  35. Function.b Get_Host_By_Address{address.l,port,player}
  36.   SHARED host(),hostlen()
  37.  
  38.   *a.hostent=gethostbyaddr_(address,4,2)  ; check wether host exists- we're not being shammed
  39.  
  40.   If *a.hostent=0
  41.     Security_Warning{"Couldn't get Localhost name!",#HIGH}
  42.     Function Return False
  43.   EndIf
  44.  
  45.   bb=CopyMem_(*a.hostent\h_addr_list\ItemA,&host(player)\sin_addr,*a.hostent\h_length) ; copy details to player's host
  46.                                                                                        ; newtype to host
  47.   host(player)\sin_port=port               ;Set port number
  48.   host(player)\sin_family=2                ;Set type to AT_INET
  49.   hostlen(player)=SizeOf.sockaddrin        ;Get length of structure sockaddrin
  50.   Function Return True
  51. End Function
  52.  
  53. .Localhost_Name
  54. Function.s Localhost_Name{}
  55.     If OpenFile (0,"ENV:HOSTNAME")
  56.        FileInput 0
  57.        While NOT Eof(0)
  58.          a$=a$+Inkey$
  59.        Wend
  60.        CloseFile 0
  61.        WindowInput 0
  62.        Function Return a$
  63.     EndIf
  64.     Function Return "localhost"
  65. End Function
  66.  
  67. .Initialise_UDP
  68. Function Initialise_UDP{port.w}
  69.   SHARED sock.l,host(),hostlen(),port_used,hostname,tcp_stack
  70.   SHARED UDPmem.l
  71.   ;
  72.   ; Open UDP socket and bind it to a port number
  73.   ; Return true or False if successful or not
  74.   ;
  75.  
  76.   If tcp_stack=False    ; if we've haven't already Initialised UDP
  77.     CNIF #NO_CONNECTION=1   ; if not connected to the `net- just running locally
  78.       host$=hostname
  79.     CELSE                   ; are connected to the net or have been since computer was booted up
  80.       host$=Localhost_Name{}
  81.     CEND
  82.  
  83.     lib.l=OpenLibrary_("bsdsocket.library",0)   ; check to see if a TCP/IP stack is running
  84.     If lib=0
  85.       Security_Warning{"TCP/IP stack not running!",#HIGH}
  86.       Function Return False
  87.     Else
  88.       CloseLibrary_(lib)           ; close lib again or Miami won't exit
  89.       sock.l=socket_(2,2,0)        ; open UDP socket
  90.       If sock=-1
  91.         Security_Warning{"Couldn't open UDP socket!",#HIGH}
  92.         Function Return False
  93.       Else
  94.         If Get_Host_By_Name{host$,port,0}=False
  95.           Function Return False
  96.         EndIf
  97.         temp=0
  98.         port_used=port
  99.         Repeat       ; for testing on localhost- keep trying one port at a time after #LOCALPORT to find a free port
  100.           host(0)\sin_port=port_used
  101.           If bind_(sock,host(0),hostlen(0))=0    ; bind socket to port so we can
  102.             tcp_stack=True                     ; note that we have initialised the UDP socket
  103.             UDPmem=AllocMem($2000,0)       ;Allocate temp buffer used for all UDP reads
  104.             Function Return True           ; receive data on port
  105.           Else
  106.             port_used+1
  107.             temp+1
  108.           EndIf
  109.         Until temp=10
  110.         Security_Warning{"Couldn't Bind a UDP socket!",#HIGH}
  111.       EndIf
  112.     EndIf
  113.   Else
  114.     Function Return True  ; if UDP socket is already initialised
  115.   EndIf
  116.   Function Return False
  117. End Function
  118.  
  119. .ReadUDP
  120. Function .s ReadUDP{}
  121.   SHARED sock.l,UDPmem.l,temphost,temphostlen
  122.  
  123.   ; This Function reads data from the socket it is bound to.
  124.   ; If there is no messages then it will return an empty string =""
  125.  
  126.   sockread.l=0                              ;Clear Readmask
  127.   sockread.l BitSet sock.l                  ;Set Readmask on our socket
  128.   e=IoctlSocket_(sock.l,#FIONREAD,UDPmem.l) ;How much data is there?
  129.   f.l=Peek.l(UDPmem.l)                      ;Place value in f
  130.  
  131.   If f>0                                    ; any data waiting
  132.     temphostlen=SizeOf .sockaddrin
  133.     c=recvfrom_(sock.l,UDPmem.l,f,0,temphost,temphostlen)  ;Read all data waiting on socket
  134.                                                            ;and get host it was sent from in temphost
  135.     If c>0    ; if there any data waiting
  136.         a=0 : c$=""
  137.         Repeat
  138.             c$=c$+Chr$(Peek.b(UDPmem+a)) : a+1    ; build string
  139.         Until a=c
  140.     EndIf
  141.  
  142.   EndIf
  143.  
  144.   Function Return c$
  145. End Function
  146.  
  147. .WriteUDP
  148. Statement WriteUDP{ad.l,size.w,player}
  149.   SHARED sock.l,host(),hostlen(),temphost,temphostlen
  150.  
  151.   ; This routine writes data via UDP
  152.  
  153.   sockwrite.l=0                         ;Clear Writemask
  154.   sockwrite.l BitSet sock.l             ;set Writemask on our socket
  155.   g=WaitSelect_(2,0,&sockwrite.l,0,0,0) ;Wait until server is ready to read our data
  156.  
  157.   If player>0
  158.     c=sendto_(sock.l,ad,size,0,host(player),hostlen(player))    ;Send data to online host
  159.   Else
  160.     c=sendto_(sock.l,ad,size,0,temphost,temphostlen)            ;Send data to host that's not connected
  161.   EndIf
  162. End Statement
  163.  
  164. .Close_UDP           ; close down UDP socket and read buffer
  165. Statement Close_UDP{}
  166.   SHARED UDPmem,sock.l,tcp_stack
  167.  
  168.   If UDPmem>0
  169.     FreeMem UDPmem,$2000   ; free UDP read memory buffer
  170.     UDPmem=0
  171.   EndIf
  172.   If sock>=0      ; if we've successfully opened a socket then close it
  173.     CloseSocket_(sock)
  174.     CNIF #COMMS_DEBUG=1
  175.       Comms_Debug{"Socket closed",#LOW}
  176.     CEND
  177.   EndIf
  178.   tcp_stack=False
  179. End Statement
  180.  
  181.  
  182.